﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include <stdexcept>
using namespace std;

/*
* string 构造函数；
* string();//创建一个空的字符串，例如：string str；
* string(const string& str);//使用一个string对象初始化另一个string对象；
* string(const char* s);//使用字符串s初始化；
* string(int n,char c);//使用n个字符c初始化；
*
* string基本赋值操作；
* string& operator=(const char* s);//char* 类型字符串，赋值给当前的字符串；
* string& operator=(const string& s);//把字符串s赋值给当前的字符串；
* string& operator=(const char c);//字符赋值给当前的字符串；
* string& assign(const char* s);//把字符串s赋给当前的字符串；
* string& assign(const char* s,int n);//把字符串s的前n个字符赋给当前的字符串；
* string& assign(const string& s);//把字符串s赋给当前字符串；
* string& assign(int n,char c);//用n个字符c赋给当前字符串；
* string& assign(const string &s,int start,int n);//将s从start开始n个字符赋值给字符串；
*/
/*
* string存取字符操作；
* char& operator[](int n);//通过[]方式取字符；
* char& at(int n);//通过at方法获取字符；
*/
/*
* string拼接操作
* string& operator+=(const string& str)//重载+=操作符
* string& operator+=(const char* str)//重载+=操作符
* string& operator+=(const char c)//重载+=操作符
* string& append(const char* s)//把字符串s拼接到当前字符串结尾
* string& append(const char* s,int n)//把字符串s的前n个字符拼接到当前字符串结尾
* string& append(const string& s)//同operator+=()
* string& append(const string& s,int pos,int n)//在字符串s中，从pos开始的n个字符拼接到当前字符串结尾
* string& append(int n,char c)//在当前字符串结尾添加n个字符c
*
* string查找和替换
* int find(const string& str,int pos = 0) const;//查找str第一次c出现位置，从pos开始查找
* int find(const char* s,int pos = 0) const;//查找s第一次出现位置，从pos开始查找
* int find(const char* s,int pos,int n) const;//从pos位置查找s的前n个字符第一次位置
* int find(const char c,int pos = 0) const;//查找字符c第一次出现位置
* int rfind(const string& str,int pos = npos) const;//查找str最后一次位置，从pos开始查找
* int rfind(const char* s,int pos = npos) const;//查找s最后一次出现位置，从pos开始查找
* int rfind(const char* s,int pos,int n) const;//从pos查找s的前n个字符最后一次位置
* int rfind(const char c,int pos = 0) const;//查找字符c最后一次出现位置
* string& replace(int pos,int n,const string& str);//替换从pos开始n个字符为字符串str
* string& replace(int pos,int n,const char* s);//替换从pos开始的n个字符为字符串s
*/
/*
* string比较操作
* compare函数在>时返回1，<时返回-1，==时返回0；
* 比较区分大小写，比较时参考字典顺序，排在越前面的越小；
* 大写的A比小写的a小；
*
* int compare(const string& s) const;//与字符串s比较
* int compare(const char* s) const;//与字符串s比较
*/
/*
* string子串
* string substr(int pos = 0,int n = npos) const;//返回由pos开始的n个字符组成的字符串；
*/
/*
* string插入和删除操作
* string& insert(int pos,const char* s);//插入字符串
* string& insert(int pos,const string& s);//插入字符串
* string& insert(int pos,int n,char c);//在指定位置插入n个字符
* string& erase(int pos,int n = npos);//删除从pos位置开始的n个字符
*/
void funcChar(string s)
{
	cout << s << endl;
}
void funcStr(const char* s)
{
	cout << s << endl;
}
void testString()
{
	//1.默认构造；
	string str;
	//2.拷贝构造；
	string str2(str);
	string str3 = str2;

	string str4 = "abcd";
	string str5(10, 'a');
	cout << str4 << endl;//abcd
	cout << str5 << endl;//aaaaaaaaaa

	//3.基本赋值；
	str = "hello";
	str2 = str4;

	//4.string& assign(const char* s,int n);//把字符串s的前n个字符赋给当前的字符串；
	str3.assign("world", 4);
	cout << str3 << endl;//worl

	//5.string& assign(const string &s,int start,int n);//将s从start开始n个字符赋值给字符串；
	string str6;
	str6.assign(str, 1, 3);
	cout << str6 << endl;//ell

	string s = "hello world";
	for (int i = 0; i < s.size(); ++i)
	{
		cout << s[i] << endl;//h,...,d
		cout << s.at(i) << endl;//h,...,d
	}
	//6.[]和at区别：[]访问，越界会直接挂掉，at会抛出异常；
	try
	{
		//cout << s[100] << endl;
		cout << s.at(100) << endl;//invalid string position
	}
	catch (out_of_range& e)
	{
		cout << e.what() << endl;
	}
	catch (...)
	{
		cout << "越界异常！" << endl;//越界异常！
	}

	//7.拼接；
	string s1 = "我";
	string s2 = "爱北京";
	s1 += s2;
	cout << s1 << endl;//我爱北京

	s1.append("天安门");
	cout << s1 << endl;//我爱北京天安门

	//8.find查找；
	string sf = "abcdefg";
	//int pos = sf.find("bc");
	//9.找不到返回是-1；
	int pos = sf.find("bcf");
	cout << "pos= " << pos << endl;//1 --> -1

	//10.rfind和find结果一样，内部查找顺序相反；
	int posR = sf.rfind("bc");
	cout << "posR= " << posR << endl;//1

	//11.替换：替换从pos开始n个字符为字符串str；
	string sr = "world";
	//sr.replace(1, 3, "123");
	sr.replace(1, 3, "1234");
	cout << sr << endl;//w123d --> w1234d

	//string sc1 = "abc";
	//string sc1 = "bbc";
	string sc1 = "abc";
	//string sc2 = "abc";
	string sc2 = "abcd";

	//sc1 等于 sc2！--> sc1 大于 sc2！--> sc1 小于 sc2！
	if (sc1.compare(sc2) == 0)
	{
		cout << "sc1 等于 sc2！" << endl;
	}
	else if (sc1.compare(sc2) == 1)
	{
		cout << "sc1 大于 sc2！" << endl;
	}
	else
	{
		cout << "sc1 小于 sc2！" << endl;
	}

	string ss1 = "abcde";
	string ss2 = ss1.substr(1, 3);
	cout << "ss2= " << ss2 << endl;//bcd

	//12.需求：查找一个邮件的用户名；
	string email = "zhangtao@sina.com";
	int posU = email.find("@");
	cout << "posU= " << posU << endl;//8
	string userName = email.substr(0, posU);
	cout << "用户名为：" << userName << endl;//zhangtao

	string  si = "hello";
	si.insert(1, "456");
	cout << si << endl;//h456ello
	//13.删除；
	si.erase(1, 3);
	cout << si << endl;//hello

	//14.string和c-style字符串转换；
	string strC1 = "thinkpad";
	//string --> const char*
	const char* pC = strC1.c_str();

	//15.const char* 隐式类型转换为string；
	funcChar(pC);//thinkpad

	//const char* --> string
	string strC2(pC);
	//16.string 不能隐式类型转换为char*；
	//funcStr(strC2);

	string strAnd = "abcdefg";
	char& a = strAnd[2];
	char& b = strAnd[3];

	a = '1';
	b = '2';

	cout << strAnd << endl;//ab12efg
	cout << (int*)strAnd.c_str() << endl;//008FF84C --> 004FF944

	//strAnd = "pppppppppppppppp";
	strAnd = "pppp";

	//a = '1';
	//b = '2';
	a = '1';
	b = '2';

	cout << strAnd << endl;//pppppppppppppppp --> pp12
	cout << (int*)strAnd.c_str() << endl;//00C801B0 --> 004FF944

	//17.写一个函数，函数内部将string字符串中的所有小写字母都变为大写字母；
	string strLetter = "abCdEfg";
	for (int i = 0; i < strLetter.size(); ++i)
	{
		//strLetter[i] = toupper(strLetter[i]);
		//18.全部变小写；
		strLetter[i] = tolower(strLetter[i]);
	}
	cout << strLetter << endl;//ABCDEFG --> abcdefg
}

//main319：string字符串容器
int main319()
{
	testString();

	system("pause");
	return EXIT_SUCCESS;
}